package QianFeng07.IODemo.ByteAndCharStream;

import java.io.*;

/**
 * 字符流：
 * 字符输出流：Write，对文件的操作使用子类：FileWrite
 * 字符输入流：Reader，对文件的操作使用子类：FileReader
 *
 * 每次操作的单位是一个字符
 * 文件字符操作流会自带缓存，默认大小为1024字节，在缓存满后，或手动刷新缓存，或关闭流时会把数据写入文件
 *
 * 字节流与字符流的区别：
 * 在所有的流操作里。字节永远是最基础的。任何基于字节的操作都是正确的。无论你是文本文件还是二进制的文件。
 * 如果确认流里面只有可打印的字符，包括英文的和各种国家的文字，也包括中文，那么可以考虑用字符流。
 * 由于编码不同，多字节的字符可能占用多个字节。比如GBK的汉字就占用2个字节，而UTF 8的汉字就占用3个字节。
 * 所以，字符流是根据指定的编码，将1个或多个字节转化为java里面的unicode的字符，然后进行操作。
 * 字符操作一般使用Writer,Reader等，字节操作一般都是InputStream, OutputStream以及各种包装类,
 * 比如BufferedInputStream和BufferedOutputStream等。
 *
 * 总结:如果你确认你要处理的流是可打印的字符，那么使用字符流会看上去简单一点。如果不确认，那么用字节流总是不会错的。
 *      一般操作非文本文件时，使用字节流；操作文本文件时，建议使用字符流
 **/
public class CharStreamDemo {
    public static void main(String[] args) {
        out();
        in();
    }

    //输入流
    private static void in() {
        //1.确定目标文件
        File file = new File("F:\\Test\\Test.txt");
        try {
            //2.构建一个文件输入对象
            Reader inputStream = new FileReader(file);
            char[] chars = new char[1];
            int len = -1;//表示每次读取的字符长度
            StringBuilder stringBuilder = new StringBuilder();
            //3.把数据读入到数组中，并返回读取的字节数，当不等于-1时，表示读取到数据，等于-1表示文件以及读取完毕
            while ((len = inputStream.read(chars)) != -1) {
                //根据读取到的字符数组，再转换为字符串内容，添加到StringBuilder中
                stringBuilder.append(new String(chars, 0, len));
            }
            //关闭输入流
            inputStream.close();
            System.out.println(stringBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //输出流
    private static void out() {
        //1.确定目标文件
        File file = new File("F:\\Test\\Test.txt");
        try {
            //2.构建一个文件输出对象
            Writer outputStream = new FileWriter(file, true); //append 为原来的文件中追加内容，去掉则是覆盖
            //3.把内容写入文件中
            outputStream.write("。不思量。自难忘"); //先写入到缓存中，不会直接写入文件中，只有超出缓存才会写入
            //4.关闭流
            outputStream.close();//把缓存中的内容写入文件中
            System.out.println("write success!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
